package cn.com.xy.sms.sdk.service.msgurlservice;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import cn.com.xy.sms.sdk.Iservice.XyCallBack;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.entity.MatchCacheManager;
import cn.com.xy.sms.sdk.db.entity.MsgUrlManager;
import cn.com.xy.sms.sdk.dex.DexUtil;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;
import cn.com.xy.sms.sdk.net.NewXyHttpRunnable;
import cn.com.xy.sms.sdk.net.util.ServerUtil;
import cn.com.xy.sms.sdk.util.DuoquUtils;
import cn.com.xy.sms.sdk.util.JsonUtil;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;

import cn.com.xy.sms.sdk.db.base.BaseManager;
import cn.com.xy.sms.util.ParseSmsMessage;
import cn.com.xy.sms.util.SdkCallBack;
import cn.com.xy.sms.sdk.util.SdkCache;
import android.content.ContentValues;
import android.os.Process;
/*SDK-616 hewengao 20160912 start*/
import cn.com.xy.sms.sdk.threadpool.SmartSmsThreadPoolManager;
/*SDK-616 hewengao 20160912 end*/
public class MsgUrlService {
	 
		public static final int RESULT_NOT_IMPL = -999;
        // validStatus:-1黑名单类型的域名、1非域名库类型的域名、2白名单类型的域名
		public static final int RESULT_ERROR_PARA = -4;//参数错误
    	public static final int RESULT_BLACK_LIST = -1; 
    	public static final int RESULT_NOT_YUMING = 1;
    	public static final int RESULT_WHITE_LIST = 2;  
    	
    	public static final int RESULT_THIRD_MIN_LEVLE = RESULT_BLACK_LIST;
    
	   public static final int RESULT_TOKEN_FLASH = 403;//token过期
	   public static final int RESULT_SERVER_ERROR = 404;//服务器错误
	   public static final int RESULT_NO_NET = 405;//没有网络
	   public static final int RESULT_NOT_FIND = 406;//没有找到
	   
	   
//	   public static final HashMap<String,Integer> finalresultMap = new HashMap<String,Integer>();

//	   public static int finalresult = -4;
	   
//	   public static ExecutorService pool = Executors.newFixedThreadPool(1);

    public static void executeRunnable(Runnable runnable) {
        /*SDK-616 hewengao 20160912 start*/
//        SmartSmsThreadPoolManager.msgUrlPool.execute(runnable);
        SmartSmsThreadPoolManager.netWebPool.execute(runnable);
        /*SDK-616 hewengao 20160912 end*/
    }

	   /**
	    * 提取url方法多个url用_ARR_隔开
	    * @param msgid
	    * @param phone
	    * @param msg
	    * @param msgtime
	    * @param extend
	    * @return
	    */
	   public static String pickUrlFromMsg(String msgid,String phone,String msg,String msgtime,final Map<String,String> extend){	        
		   final String urls = DexUtil.catchUrls(msg, null);
		   executeRunnable(new Runnable() {
			
			@Override
			public void run() {
				try {
					if(StringUtils.isNull(urls))return;
				MsgUrlManager.saveOrUpdate(urls);
				} catch (Throwable e) {
					LogManager.e(Constant.TAG, e.getMessage(), e);
				}
								
			}
		   });
		   return urls;   
	   }

			 
	   public static int checkValidUrl(final String msgid,final String phone,final String msg,final String url,final Map<String,String> extend,final XyCallBack xyCallBack){
			   final HashMap<String,Integer> finalresultMap = new HashMap<String,Integer>();
			   int type = XyUtil.checkNetWork(Constant.getContext(), 2);
			   try {			   		
					   if(StringUtils.isNull(url)) {
					       /*SDK-610 mobaohua 2016-09-07 start*/
					       XyUtil.doXycallBackResult(xyCallBack, RESULT_ERROR_PARA);
					       /*SDK-610 mobaohua 2016-09-07 end*/
					       return RESULT_ERROR_PARA;
					   }
					   
						final String[] arr = url.split(MsgUrlManager.DIVDER);
						if(arr==null||arr.length<=0){
						    /*SDK-610 mobaohua 2016-09-07 start*/
						    XyUtil.doXycallBackResult(xyCallBack, RESULT_ERROR_PARA);
						    /*SDK-610 mobaohua 2016-09-07 end*/
							return RESULT_ERROR_PARA;
						}					
//						LogManager.i("checkValidUrl", "arr.length="+arr.length);
						//先查本地缓存
						int implResult = DuoquUtils.getSdkDoAction().checkValidUrl(msgid, phone, msg, url, extend);
						boolean hasThirdImpl = (implResult != RESULT_NOT_IMPL);
						Map<String,Object>  resultMap = queryLocal(msgid, phone, msg, url, arr, hasThirdImpl, extend);
						if(resultMap.containsKey("localfind")){
							Integer result = (Integer)resultMap.get("result");
//							LogManager.d("checkValidUrl", "本地查询到 result=",result);
							/*SDK-610 mobaohua 2016-09-07 start*/
							XyUtil.doXycallBackResult(xyCallBack, result);
							/*SDK-610 mobaohua 2016-09-07 end*/
							return result;
						}	
						
						//假如本地没有查到缓存，继续识别
						if(hasThirdImpl){
							LogManager.d("checkValidUrl", "第三方查询");
							//假如第三方已经实现
							int result = thirdValid(msgid, phone, msg, url, arr, extend);
							MatchCacheManager.updateCheckStatu(url, result);
							/*SDK-610 mobaohua 2016-09-07 start*/
							XyUtil.doXycallBackResult(xyCallBack, result);
							/*SDK-610 mobaohua 2016-09-07 end*/
							return result;
						}else{						
							 if (type == -1) {	
							     /*SDK-610 mobaohua 2016-09-07 start*/
							     XyUtil.doXycallBackResult(xyCallBack, RESULT_NO_NET);
							     /*SDK-610 mobaohua 2016-09-07 end*/
									return RESULT_NO_NET;
					          }
							 /*SDK-480 songzhirong 20160613 start*/
							 NetUtil.executeRunnable(new Runnable() {
                                
                                @Override
                                public void run() {
                                    /*SDK-438 /songzhirong/2016.05.17---start---*/
                                    checkValidUrlNet(msgid, phone, msg, url,arr, extend,false,finalresultMap,xyCallBack);  
                                    /*SDK-438 /songzhirong/2016.05.17---end---*/
                                    
                                }
                            });
							 /*SDK-480 songzhirong 20160613 end*/
						}
					
						
				} catch (Throwable e) {
					// TODO: handle exception
				}finally{
					 if (type != -1){
							updateCheckValidUrl();
					 }
				}
			   /*SDK-438 /songzhirong/2016.05.17---start---*/
			   if(finalresultMap.containsKey(url)){
			       /*NUBIA-309 zhaojiangwei 20170330 start */
			       int opRet = RESULT_NOT_FIND;
			       try{
			           opRet = finalresultMap.remove(url);
			       }
			       catch (Exception e) {
                    // TODO: handle exception
			       }
			       /*SDK-610 mobaohua 2016-09-07 start*/
			       XyUtil.doXycallBackResult(xyCallBack, opRet);
			       /*SDK-610 mobaohua 2016-09-07 end*/
				   return opRet;
				   /*NUBIA-309 zhaojiangwei 20170330 end */
			   }else{
			       /*SDK-610 mobaohua 2016-09-07 start*/
			       XyUtil.doXycallBackResult(xyCallBack, RESULT_NOT_FIND);
			       /*SDK-610 mobaohua 2016-09-07 end*/
				   return RESULT_NOT_FIND;
			   }
			   /*SDK-438 /songzhirong/2016.05.17---end---*/

		   }
			


	   public static Map<String,Object> queryLocal(final String msgid,final String phone,final String msg,final String url, final String[] arr,boolean hasThirdImpl,final Map<String,String> extend){
		   HashMap<String,Object> map = new HashMap<String,Object>();		
		   int result = 0;	
		   boolean hasNotCheck = false;
		   if(arr.length==1){
				result = MsgUrlManager.queryStatuByUrl(url,hasThirdImpl);
				if(result!=MsgUrlManager.NOT_CHECK){
					//假如本地已有缓存，直接返回结果
//					LogManager.d("checkValidUrl", "return allcheck="+result);
					map.put("result", result);
					map.put("localfind", true);
					return map;
				}
			}else{
				HashMap<String,Object> temp = MsgUrlManager.queryStatuByUrls(arr,hasThirdImpl);
				result = (Integer)temp.get("statu");
				if(temp.containsKey("hasNotCheck")){
					hasNotCheck = true;
				}
				if(!hasNotCheck){
					//假如本地已有缓存，直接返回结果
					map.put("result", result);
					map.put("localfind", true);
					return map;
				}else{		
					boolean isUnderMin = false;
					if(hasThirdImpl){
						//假如url中有，没有检测过的，但是已经低于第三方识别的最低值，就返回，再在调用后台识别
						if(result <= RESULT_THIRD_MIN_LEVLE){
							result = RESULT_THIRD_MIN_LEVLE;
							isUnderMin = true;
						}							
					}else{
						//假如url中有，没有检测过的，但是已经包括黑名单，返回黑名单，并在后头监测没有监测的url
						if(result <= MsgUrlManager.BLACK_LIST){
							result = RESULT_BLACK_LIST;	
							isUnderMin = true;
						}
					}	
					 /*SDK-438 /songzhirong/2016.05.17---start---*/
					//后台请求	
                    checkValidUrlNet(msgid, phone, msg, url, arr, extend, true, null, null);
					 /*SDK-438 /songzhirong/2016.05.17---end---*/

					if(isUnderMin){
						map.put("result", result);
						map.put("localfind", true);
						return map;					
					}
				}
			}		
			return map;					
	   }
	   
	   public static int thirdValid(final String msgid,final String phone,final String msg,final String url,final String[] arr ,final Map<String,String> extend){
		    int min = Integer.MAX_VALUE;
			if(arr.length==1){
				int tempResult = DuoquUtils.getSdkDoAction().checkValidUrl(msgid, phone, msg, url, extend);
				MsgUrlManager.saveOrUpdateThirdStatu(url, tempResult);			
				return tempResult;		
			}else{
				int index = -1;				
				try {
					for(int i=0;i<arr.length;i++){
						int tempResult = DuoquUtils.getSdkDoAction().checkValidUrl(msgid, phone, msg, arr[i], extend);
						MsgUrlManager.saveOrUpdateThirdStatu(arr[i], tempResult);
						index = i;	
						if(tempResult<=min){
							min = tempResult;
						}						
						if(tempResult <= RESULT_THIRD_MIN_LEVLE)return RESULT_THIRD_MIN_LEVLE;
					}
							
				} catch (Throwable e) {
					// TODO: handle exception
				}finally{
					saveLeft(msgid,phone,msg,arr,index,extend);
				}
			
			}	
			return min;		
	   }

	   /*SDK-438 /songzhirong/2016.05.17---start---*/

	   public static void checkValidUrlNet(String msgid,String phone,String msg,final String url,String[] arr,final Map<String,String> extend,final boolean newThread,final HashMap<String,Integer> finalresultMap,final XyCallBack sdkCallBack){
		 	final String dataString = ServerUtil.getcheckValidUrlReq(phone, arr);
			 /*SDK-438 /songzhirong/2016.05.17---end---*/

		 	try {
		 		if(!StringUtils.isNull(dataString)){
		            NetUtil.requestNewTokenIfNeed(extend);
		            /* SDK-526 huangzhiqiang 20160713 start */
		            final String token = NetUtil.getToken();
		            /* SDK-526 huangzhiqiang 20160713 end */
		 			XyCallBack callBack = new XyCallBack(){

						@Override
						public void execute(Object... obj) {

							if (obj != null) {
								String resutCode = obj[0].toString();
								if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
//                                  NetUtil.syncRequestNewToken(extend);
//									if(finalresultMap!=null){
//										finalresultMap.put(url, RESULT_TOKEN_FLASH);
//										/*SDK-438 /songzhirong/2016.05.17---start---*/
//										XyUtil.doXycallBackResult(sdkCallBack, RESULT_TOKEN_FLASH);
//										/*SDK-438 /songzhirong/2016.05.17---end---*/
//									}
                                    /* SDK-526 huangzhiqiang 20160713 start */
                                    NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.URL_VALIDITY, dataString,
                                            Constant.FIVE_MINUTES, newThread, false, true, extend, token, this);
                                    return;
                                    /* SDK-526 huangzhiqiang 20160713 end */
								} 

								if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_PARE_ERR)
										|| resutCode.equals(NewXyHttpRunnable.ERROR_CODE_SERVICE_ERR)) {
									// 网络失败
									if(finalresultMap!=null){
										finalresultMap.put(url, RESULT_SERVER_ERROR);
										/*SDK-438 /songzhirong/2016.05.17---start---*/
										XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
										/*SDK-438 /songzhirong/2016.05.17---end---*/
									}
								} else {
									if (resutCode.equals("0") && obj.length == 2) {
										String response = obj[1].toString();
										if(StringUtils.isNull(response)){
											if(finalresultMap!=null){
												finalresultMap.put(url, RESULT_SERVER_ERROR);
												/*SDK-438 /songzhirong/2016.05.17---start---*/
												XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
												/*SDK-438 /songzhirong/2016.05.17---end---*/

											}
										}else{
											try {
												JSONArray jsonArray = new JSONArray(response);
												int temp = getVailResult(jsonArray); 
												if(finalresultMap!=null){
													finalresultMap.put(url, temp);
													/*SDK-438 /songzhirong/2016.05.17---start---*/
													XyUtil.doXycallBackResult(sdkCallBack, temp);
													/*SDK-438 /songzhirong/2016.05.17---end---*/
												}
												saveUrlResult(jsonArray,url,temp,newThread);												
											} catch (Throwable e) {												
//												e.printStackTrace();
					                            LogManager.e(Constant.TAG, "checkValidUrlNet: ", e);

												if(finalresultMap!=null){
													finalresultMap.put(url, RESULT_SERVER_ERROR);
													/*SDK-438 /songzhirong/2016.05.17---start---*/
													XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
													/*SDK-438 /songzhirong/2016.05.17---end---*/
												}
											}
										}										
									} else { // 网络失败
										if(finalresultMap!=null){
											finalresultMap.put(url, RESULT_SERVER_ERROR);
											/*SDK-438 /songzhirong/2016.05.17---start---*/
											XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
											/*SDK-438 /songzhirong/2016.05.17---end---*/
										}
									}
								}
							} else { // 网络失败
								if(finalresultMap!=null){
									finalresultMap.put(url, RESULT_SERVER_ERROR);
                                    /*SDK-438 /songzhirong/2016.05.17---start---*/
									XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
                                    /*SDK-438 /songzhirong/2016.05.17---end---*/
								}
							}
						}
		 				
		 			};
		            NetUtil.executeNewServiceHttpRequest(NetUtil.URL_VALIDITY,dataString, callBack,newThread,false, true,extend);
		 		}
			} catch (Throwable e) {
			    /*SDK-610 mobaohua 2016-09-07 start*/
			    XyUtil.doXycallBackResult(sdkCallBack, RESULT_SERVER_ERROR);
			    /*SDK-610 mobaohua 2016-09-07 end*/
               LogManager.e(Constant.TAG, "checkValidUrlNet: ", e);
			}
		 
	 }
	   public static void saveUrlResult(final JSONArray jsonArray,final String url,final int result,final boolean newThread){
			 if(jsonArray==null || jsonArray.length() <=0)return;
			 if(newThread){
				 executeRunnable(new Runnable() {
						
						@Override
						public void run() {
							try {
								saveUrlResult(jsonArray,url,result);
							} catch (Throwable e) {
								LogManager.e(Constant.TAG, e.getMessage(), e);
							}
						}
					   });
			 }else{
				 saveUrlResult(jsonArray,url,result);
			 }
		 }
		 
	public static void saveUrlResult(JSONArray jsonArray,final String url,int result){
		 if(jsonArray==null || jsonArray.length() <=0) return;
		 MsgUrlManager.saveOrUpdate(jsonArray);
		 MatchCacheManager.updateCheckStatu(url, result);
	}
	   
    private static void saveLeft(final String msgid, final String phone, final String msg, final String[] arr,
            final int startIndex, final Map<String, String> extend) {
        try {
            if (startIndex < 0 || startIndex > arr.length - 1) {
                return;
            }
            executeRunnable(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int i = startIndex; i < arr.length; i++) {
                            int tempResult = DuoquUtils.getSdkDoAction().checkValidUrl(msgid, phone, msg, arr[i],
                                    extend);
                            MsgUrlManager.saveOrUpdateThirdStatu(arr[i], tempResult);
                        }
                    } catch (Throwable e) {
                        LogManager.e(Constant.TAG, e.getMessage(), e);
                    }
                }
            });
        } catch (Throwable e) {
            // TODO: handle exception
        }
    }
		
	 private static int getVailResult(JSONArray jsonArray){
		 if(jsonArray==null || jsonArray.length() <=0) return RESULT_SERVER_ERROR;
		 int min = Integer.MAX_VALUE;
		 for(int i=0;i<jsonArray.length();i++){
	    		JSONObject json = jsonArray.optJSONObject(i);	 
	    		int  statu = json.optInt("validStatus");
	    		if(statu <= min){
	    			min = statu;
	    		}
	    		if(statu <= RESULT_BLACK_LIST){
	    			return RESULT_BLACK_LIST;
	    		}
	    	}
		 return min;
	 }
	 
	 static boolean isUpdating = false;
	 public static synchronized void updateCheckValidUrl(){
		  if(isUpdating)return;
		  isUpdating = true;
		  executeRunnable(new Runnable() {
			
			@Override
			public void run() {
				try {
					JSONArray jsonArray = MsgUrlManager.queryCheckTimeExpireData();
				  checkValidUrlNetBatch(jsonArray, true);
				} catch (Throwable e) {
					LogManager.e(Constant.TAG, e.getMessage(), e);
				}
				  
				
			}
		});
		

    }
	  
	  public static void checkValidUrlNetBatch(JSONArray jsonArray,final boolean newThread){
		    
		 	try {
		 		if(jsonArray==null||jsonArray.length()<=0)return;
			 	final String dataString = ServerUtil.getcheckValidUrlReq(jsonArray);

		 		if(!StringUtils.isNull(dataString)){
		 			NetUtil.requestNewTokenIfNeed(null);
                    /* SDK-526 huangzhiqiang 20160713 start */
                    final String token = NetUtil.getToken();
                    /* SDK-526 huangzhiqiang 20160713 end */
		 			XyCallBack callBack = new XyCallBack(){

						@Override
						public void execute(Object... obj) {
                            if (obj == null || obj.length < 1) {
                                return;
                            }
                            String resutCode = obj[0].toString();
                            if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
                                /* SDK-526 huangzhiqiang 20160713 start */
                                NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.URL_VALIDITY, dataString,
                                        Constant.FIVE_MINUTES, newThread, false, true, null, token, this);
                                return;
                                /* SDK-526 huangzhiqiang 20160713 end */
                            }
                            if (!resutCode.equals("0") || obj.length < 2) {
                                return;
                            }
                            String response = obj[1].toString();
                            if (StringUtils.isNull(response)) {
                                return;
                            }
                            try {
                                JSONArray jsonArray = new JSONArray(response);
                                MsgUrlManager.saveOrUpdate(jsonArray);
                                MatchCacheManager.updateCheckStatu(jsonArray);
                            } catch (Throwable e) {
                                LogManager.e(Constant.TAG, "checkValidUrlNetBatch: ", e);
                            }
						}
		 			};
		            NetUtil.executeNewServiceHttpRequest(NetUtil.URL_VALIDITY,dataString, callBack,newThread,false, true,null);
		 		}
			} catch (Throwable e) {
//				e.printStackTrace();
                LogManager.e(Constant.TAG, "checkValidUrlNetBatch: ", e);

			}finally{
				synchronized (MsgUrlService.class) {
					isUpdating = false;
				}
			}
	 }
	
	  /*MEIZU-1142 zhaojiangwei 20160908 start*/  
	public static void checkUrlFromMsg(final String msgId, final String phoneNum, final String smsCenterNum,
			final String smsContent, final long smsReceiveTime, final Map<String, String> extend,
			final SdkCallBack xyCallBack, boolean scrollFing) throws Exception {
		if (msgId == null || phoneNum == null || smsContent == null) {
			throw new Exception("msgid or phoneNum or smsContent is null but they need value.");
		}
		final SdkCache sdkCache = SdkCache.createSdkCache(phoneNum);
		JSONObject res = sdkCache.effectiveUrlsData.get(msgId);
		if (res != null) {
			XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_HASDATA, res, msgId,
					ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
			return;
		}
		
		if (sdkCache.inQueueUrlsData.contains(msgId)) {
			XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NODATA, " inQueueUrlsData",
					msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
			return;
		}
		
        try {
            JSONObject cacheJsObj = sdkCache.cacheUrlsData.remove(msgId);
            if (cacheJsObj!=null) {
                String urlResult = cacheJsObj.optString("urls_result");
                if (!StringUtils.isNull(urlResult)) {
                    JSONObject object = new JSONObject(urlResult);
                    if (object != null) {
                        String md5 = (String) JsonUtil.getValueFromJsonObject(cacheJsObj, "msg_num_md5");
                        String md5_1 = MatchCacheManager.getMD5(phoneNum, smsContent);
                        if (md5_1 != null && md5 != null && md5_1.equals(md5)) {
                           if(urlResultIsValid(object)){
                               XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_HASDATA, object, msgId,
                                       ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
                               return;
                           }
                        }
                    }
                }   
            }
        }
        catch (Throwable e) {
            // TODO: handle exception
            LogManager.e(Constant.TAG, "checkUrlFromMsg from cache error", e);
        }
		if (!scrollFing) {
            sdkCache.inQueueUrlsData.add(msgId);
			XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NEEDPARSE, " need parse",
					msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
			// 异步识别
            /* SDK-616 hewengao 20160912 start */
			/* SDK-616 hewengao 20161028 start */
			SmartSmsThreadPoolManager.getMsgUrlPool().execute(new Runnable() {
			/* SDK-616 hewengao 20161028 end */
            /* SDK-616 hewengao 20160912 end */
				@Override
				public void run() {
					try{
						/* SDK-616 hewengao 20161028 start */
						SmartSmsThreadPoolManager.setThreadNameAndPriority(SmartSmsThreadPoolManager.TNAME_MSGURLPOOL,Process.THREAD_PRIORITY_BACKGROUND);
						/* SDK-616 hewengao 20161028 end */
						// 从tb_match数据库缓存里面读取
						JSONObject object = readUrlsResultFromDb(msgId, phoneNum, smsContent);
						boolean urlCheckValid = urlResultIsValid(object);
						if (!urlCheckValid) {
							// 缓存数据库里面还没有数据, 走识别检验流程.
							// call api
							XyCallBack innerCallBack = new XyCallBack() {
								@Override
								public void execute(Object... obj) {
									try {
										JSONObject resultObj = (JSONObject) obj[0];
										sdkCache.inQueueUrlsData.remove(msgId);
										/*SDK-677 zhaojiangwei 20161116 start */
										if(urlResultIsValid(resultObj)){
											sdkCache.effectiveUrlsData.put(msgId, resultObj);
										}
										/*SDK-677 zhaojiangwei 20161116 end */
										saveUrlsResultToDb(msgId, phoneNum, smsContent, smsReceiveTime,
												resultObj.toString());

										XyUtil.doXycallBackResult(xyCallBack,
												ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA, resultObj, msgId,
												ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
									}
									catch (Throwable e) {
										// TODO: handle exception
									}
								}
							};
							apiCheck(msgId, phoneNum, smsContent, extend, object, innerCallBack);
						}
						else {
							// 返回缓存的数据.
							XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA, object,
									msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
							sdkCache.inQueueUrlsData.remove(msgId);
							sdkCache.effectiveUrlsData.put(msgId, object);
						}
					}
					catch (Throwable e) {
						// TODO: handle exception
						sdkCache.inQueueUrlsData.remove(msgId);
						LogManager.e(Constant.TAG, "exception in msgurlservice", e);
					}
				}
			});
		}
		else {
			XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_SCOLLING, " is scrolling",
					msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG);
		}
	}
	
	
	private static boolean urlResultIsValid(JSONObject cachedObj){
	    boolean resultValid = false;
	    try {
            if (cachedObj != null) {
                String urls = cachedObj.optString("urls");
                if (StringUtils.isNull(urls)) {
                    resultValid = true;
                }
                else {
                    int status = cachedObj.optInt("validStatus", RESULT_NOT_FIND);
                    if (status >= RESULT_BLACK_LIST && status <= RESULT_WHITE_LIST) {
                        // 数据库里面有真实的缓存.
                        resultValid = true;
                    }
                }
            }
        }
        catch (Throwable e) {
            LogManager.e(Constant.TAG, "MsgUrlService urlResultIsValid error", e);
        }
	    return resultValid;
	}

    private static void apiCheck(final String msgId, final String phoneNum, final String smsContent,
			final Map<String, String> extend, final JSONObject cachedObj, final XyCallBack dataCallBack) {
		try {
			int tmpSensitive = 0;
			String tmpUrls = null;
			if (cachedObj != null) {
				tmpSensitive = cachedObj.optInt("hasSensitive");
				tmpUrls = cachedObj.optString("urls");
			}
			else {
				tmpSensitive = DexUtil.parseSensitive(smsContent);
				tmpUrls = DexUtil.catchUrls(smsContent, null);
			}
			final String urls = tmpUrls;
			final int hasSensitive = tmpSensitive;
			/*SDK-609 zhaojiangwei 20161014 start */
			boolean checkbreviary = false;
			if (extend!=null && extend.containsKey("breviary")) {
                String tmpbreviary = extend.get("breviary");
                if (tmpbreviary.equalsIgnoreCase("true")) {
                    checkbreviary = true;
                }
            }
			/*SDK-609 zhaojiangwei 20161014 start */
			if (StringUtils.isNull(urls)) {
				// 短信原文中没有url，走只判断是否有敏感字段的流程.
				JSONObject resultObj = buildUrlsResult("", hasSensitive, RESULT_NOT_FIND, cachedObj, null);
				XyUtil.doXycallBackResult(dataCallBack, resultObj);
			}
			else {
				String[] urlArrs = urls.split(MsgUrlManager.DIVDER);
				HashMap<String, Object> temp = MsgUrlManager.queryStatuByUrls(urlArrs, false);
				int result = (Integer) temp.get("statu");
				boolean checkFromHttp = false;
				/*SDK-672 zhaojiangwei 20161111 start */
				boolean access = NetUtil.checkAccessNetWork(2);
				if (temp.containsKey("hasNotCheck") && result != RESULT_BLACK_LIST) {
					// 需要网络查询
					checkFromHttp = true;
					if (!access) {
						result = RESULT_NO_NET;
					}
				}
				/*SDK-672 zhaojiangwei 20161111 end */				
				if (checkFromHttp && access) {
					// 网络查询
					final String dataString = ServerUtil.getcheckValidUrlReq(phoneNum, urlArrs, checkbreviary);
					/*SDK-683 zhaojiangwei 20161121 start */
				    NetUtil.requestNewTokenIfNeed(extend);
					/*SDK-683 zhaojiangwei 20161121 start */
					XyCallBack callBack = new XyCallBack() {
						@Override
						public void execute(Object... obj) {
							try {
								int status = RESULT_NOT_FIND;
								JSONArray jsonArray = null;
								if (obj != null && obj.length > 1) {
									String resutCode = obj[0].toString();
									// token过期.
									if (resutCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
										/* SDK-526 huangzhiqiang 20160713 start */
										final String token = NetUtil.getToken();
										NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.URL_VALIDITY, dataString,
												Constant.FIVE_MINUTES, false, false, true, null, token, this);
										/* SDK-526 huangzhiqiang 20160713 end */
									}
									// 正常返回.
									else if (resutCode.equals("0")) {
										try {
											String response = obj[1].toString();
											jsonArray = new JSONArray(response);
											status = getVailResult(jsonArray);
											saveUrlResult(jsonArray, urls, status);
										}
										catch (Throwable e) {
											LogManager.e(Constant.TAG, "MsgUrlService apiCheck saveUrlResult error", e);
										}
									}
								}
								JSONObject resultObj = buildUrlsResult(urls, hasSensitive, status, cachedObj, jsonArray);
								XyUtil.doXycallBackResult(dataCallBack, resultObj);
							}
							catch (Throwable e) {
								LogManager.e(Constant.TAG, "MsgUrlService apiCheck execute error", e);
							}
						}
					};
					NetUtil.executeNewServiceHttpRequest(NetUtil.URL_VALIDITY, dataString, callBack, false, false, true,
							extend);
				}
				else {
					// 直接返回结果(不走网络查询).
					JSONObject resultObj = buildUrlsResult(urls, hasSensitive, result, cachedObj, null);
					// 存储到tb_match
					XyUtil.doXycallBackResult(dataCallBack, resultObj);
				}
			}
		}
		catch (Throwable e) {
			LogManager.e(Constant.TAG, "MsgUrlService apiCheck error", e);
		}
	}

    private static JSONObject readUrlsResultFromDb(final String msgId, final String phoneNumber,
                                                   final String smsContent) {

        String where = "msg_id=?";
        String args[] = new String[]{msgId};
        String[] cols = new String[]{"msg_id", "msg_num_md5", "urls_result", "urls_lasttime"};
        Map<String, JSONObject> cacheMaps = MatchCacheManager.loadDataByParam(where, args, cols);
        JSONObject urlCheckObj = null;
        if (cacheMaps != null) {
            try {
                /*SDK-660 hewengao 20161103 start*/
                JSONObject cahceObj = cacheMaps.get(msgId);
                if (cahceObj != null) {
                    String msg_num_md5 = cahceObj.optString("msg_num_md5");
                    String md5_1 = MatchCacheManager.getMD5(phoneNumber, smsContent);
                    if (md5_1.equalsIgnoreCase(msg_num_md5)) {
                        String urlResutls = cahceObj.optString("urls_result");
                        if (!StringUtils.isNull(urlResutls)) {
                            urlCheckObj = new JSONObject(urlResutls);
                        }
                    }
                }
                /*SDK-660 hewengao 20161103 end*/
            } catch (Throwable e) {
                LogManager.e(Constant.TAG, "MsgUrlService readUrlsResultFromDb error", e);
            }
        }
        return urlCheckObj;
    }

	
	private static void saveUrlsResultToDb(final String msgId,
			final String phoneNumber,
			final String smsContent, final long smsReceiveTime,
			final String data) {
		try {
			String msg_num_md5 = MatchCacheManager.getMD5(phoneNumber, smsContent);
			if (!StringUtils.isNull(msg_num_md5)) {
				ContentValues matchCache = BaseManager.getContentValues(null, "msg_num_md5", msg_num_md5, "phonenum",
						StringUtils.getPhoneNumberNo86(phoneNumber), "msg_id", msgId, "urls_result",
						data == null ? "" : data, "urls_lasttime", String.valueOf(System.currentTimeMillis()));
				MatchCacheManager.insertOrUpdate(matchCache, 5);
			}
		}
		catch (Throwable e) {
			LogManager.e(Constant.TAG, "MsgUrlService saveUrlsResultToDb error", e);
		}
	}

	
	private static JSONObject buildUrlsResult(String urls, int hasSensitive, int validStatus, JSONObject cachedObj, JSONArray extmsg) {
	    JSONObject json = null;
	    if (cachedObj!=null) {
	        json = cachedObj;
	        /*SDK-609 zhaojiangwei 20161014 start */
	        json.remove("results");
	        /*SDK-609 zhaojiangwei 20161014 end */
        }
	    else{
	        json = new JSONObject();
	    }
		try {
			json.put("urls", urls);
			json.put("hasSensitive", hasSensitive);
			json.put("validStatus", validStatus);
			 /*SDK-609 zhaojiangwei 20161014 start */
			if (extmsg!=null) {
			    json.put("results", extmsg);
            }
			 /*SDK-609 zhaojiangwei 20161014 end */
			return json;
		}
		catch (Throwable e) {
			LogManager.e(Constant.TAG, "MsgUrlService buildUrlsResult error", e);
		}
		return json;
	}
	
	
	/* SDK-615 zhaojiangwei 20160912 start */
    public static void putUrlsResultData(String phone, Map<String, JSONObject> data, boolean clearPrev) {
        SdkCache sdkCache = SdkCache.createSdkCache(phone);
        synchronized (sdkCache.cacheUrlsData) {
            if (clearPrev) {
                sdkCache.clearUrlDataCache();
            }
            if (data != null) {
                sdkCache.cacheUrlsData.putAll(data);
//                for (String key : data.keySet()) {  
//                    JSONObject mapObj = data.get(key);
//                    if (mapObj!=null) {
//                        String urlResults = mapObj.optString("urls_result");
//                        if (!StringUtils.isNull(urlResults)) {
//                            try {
//                                JSONObject urlResultObj = new JSONObject();
//                                urlResultObj.put("urls_result", urlResults);
//                                urlResultObj.put("urls_lasttime", mapObj.optString("urls_lasttime"));
//                                urlResultObj.put("msg_num_md5", mapObj.optString("msg_num_md5"));
//                                
//                                sdkCache.cacheUrlsData.put(key, urlResultObj);
//                            }
//                            catch (Throwable e) {
//                    			LogManager.e(Constant.TAG, "MsgUrlService putUrlsResultData error", e);
//                            }
//                        }	
//					}
//                } 
            }
            else {
    			LogManager.d(Constant.TAG, "putUrlsResultData size is null ", null);
            }
        }
    }
    /* SDK-615 zhaojiangwei 20160912 end */
}
